using System;
using System.Collections.Generic;

namespace PentaBiz.Collections.DataCache
{
    public static class SequentialDataCacheExtensions
    {
        /// <summary>
        /// Counts the specified sequential data cache items.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sequentialDataCache">The sequential data cache.</param>
        /// <returns></returns>
        public static int Count<T>(this ISequentialDataCache<T> sequentialDataCache)
        {
            return sequentialDataCache.Count;
        }

        /// <summary>
        /// Creates <see cref="ISequentialDataCache{T}" /> from <see cref="IEnumerable{T}" />
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable">The enumerable.</param>
        /// <param name="path">The path.</param>
        /// <param name="pageSizeLimit">The page size limit.</param>
        /// <returns>
        /// new <see cref="ISequentialDataCache{T}" />
        /// </returns>
        public static ISequentialDataCache<T> ToSequentialDataCache<T>(this IEnumerable<T> enumerable, string path,
                                                                       int pageSizeLimit = 100)
            where T : class
        {
            SequentialDataCache<T> c = SequentialDataCache<T>.Initialize(path, pageSizeLimit, true);

            foreach (T item in enumerable)
            {
                c.Add(item);
            }

            return c;
        }

        /// <summary>
        /// Creates <see cref="ISequentialDataCache{T}" /> from <see cref="IEnumerable{T}" />
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable">The enumerable.</param>
        /// <param name="pageSizeLimit">The enumerable.</param>
        /// <param name="deleteOnClose">The page size limit.</param>
        /// <returns>
        /// new <see cref="ISequentialDataCache{T}" />
        /// </returns>
        public static ISequentialDataCache<T> ToSequentialDataCache<T>(this IEnumerable<T> enumerable,
                                                                       int pageSizeLimit = 100,
                                                                       bool deleteOnClose = true)
            where T : class
        {
            SequentialDataCache<T> c = SequentialDataCache<T>.Initialize(pageSizeLimit, deleteOnClose);

            foreach (T item in enumerable)
            {
                c.Add(item);
            }
            return c;
        }

        /// <summary>
        /// Creates new <see cref="ISequentialDataCache{T}" /> from <see cref="IEnumerable{T}" /> where <paramref name="itemCondition"/> takes <paramref name="itemTransformation"/>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable">The enumerable.</param>
        /// <param name="itemCondition">The item condition.</param>
        /// <param name="itemTransformation">The item transformation.</param>
        /// <param name="pageSizeLimit">The page size limit.</param>
        /// <param name="deleteOnClose">if set to <c>true</c> [delete on close].</param>
        /// <returns></returns>
        public static ISequentialDataCache<T> ToSequentialDataCache<T>(this IEnumerable<T> enumerable,
            Func<T, bool> itemCondition,
            Func<T, T> itemTransformation,
            int pageSizeLimit = 100,
            bool deleteOnClose = true
            ) where T : class
        {

            var r = SequentialDataCache<T>.Initialize(pageSizeLimit, deleteOnClose);

            foreach (var item in enumerable)
            {
                if (itemCondition(item))
                    r.Add(itemTransformation(item));
            }

            return r;
        }
    }
}